package utils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;


public class GetJsonValue {
    private String value;
    private JSONArray arrays = new JSONArray();
    private ArrayList<String> list = new ArrayList<>();
    private ArrayList<String> listAll = new ArrayList<>();

    /**
     * 传入JSON格式数据，和key，返回key对应的值。<br>
     * 如果存在多个相同的key，本方法获取的是第一个key的值
     *
     * @param jsonString$ Json格式数据
     * @param key         想取键值对的键值
     * @return value 返回键对应的值
     */
    public String getValue(String jsonString$, String key) throws JSONException {

        list.clear();
        AllValue(jsonString$, key, list);
        if (list.isEmpty()) {
            throw new JSONException("json数据中没有找到指定的key：" + key);
        }
        return list.get(0);
    }


    /**
     * 获取当前JSONObject 对象中对应key的值(只在当前传入的json数据中查询)
     */
    public String getCurrentValue(String jsonString$, String key) throws JSONException {

        String jsonString = jsonString$.trim();
        if (!(jsonString.startsWith("{") || jsonString.startsWith("["))) {
            return null;
        }
        JSONObject jsonObject;
        JSONArray jsonArray;
        Object json = new JSONTokener(jsonString).nextValue();
        if (json instanceof JSONObject) {
            jsonObject = new JSONObject(jsonString);
            Iterator<?> it = jsonObject.keys();
            while (it.hasNext()) {
                String key$ = (String) it.next();
                if (key$.equals(key)) {
                    value = jsonObject.optString(key);
                    return value;
                }
            }

        } else if (json instanceof JSONArray) {

            jsonArray = new JSONArray(jsonString);
            for (int i = 0; i < jsonArray.length(); i++) {
                String object = jsonArray.optString(i);
                if (object.startsWith("["))
                    getCurrentValue(object, key);

                JSONObject jo = jsonArray.optJSONObject(i);
                Iterator<?> it;
                try {
                    it = jo.keys();
                } catch (Exception e) {
                    System.out.println("当前json数据没有key值");
                    continue;
                }
                while (it.hasNext()) {
                    String key$ = (String) it.next();
                    if (key$.equals(key)) {
                        value = jo.optString(key);
                        return value;
                    } else {
                        if (jo.optString(key$).isEmpty()) {
                            System.out.println("the key:" + key$ + " value is null!!!");
                        }
                    }
                }
            }
        }
        return value;
    }

    /**
     * 解析JSONObject 数据，返回所有的key所对应的值，存入list集合。
     * 注意：在返回的数组遍历代码模块内，在使用本类中的getAllValue和getValue方法时，
     * 将抛出java.util.ConcurrentModificationException异常，因为该操作在同时修改同一个arraylist
     * 如果有这类操作，那么就使用不同实力调用方法
     *
     * @return 返回获取的所有的值的list集合
     */
    public List<String> getAllValue(String jsonString$, String key) throws JSONException {
        listAll.clear();
        return AllValue(jsonString$, key, listAll);
    }

    private List<String> AllValue(String jsonString$, String key, List<String> lists) throws JSONException {

        JSONObject jsonObject;
        JSONArray jsonArray;
        String jsonString = jsonString$.trim();

        if (!(jsonString.startsWith("{") || jsonString.startsWith("["))) {
            return null;
        }
        Object json = new JSONTokener(jsonString).nextValue();

        if (json instanceof JSONObject) {

            jsonObject = new JSONObject(jsonString);

            Iterator<?> it = jsonObject.keys();

            foreachJsonObject(key, jsonObject, it, lists);

        } else if (json instanceof JSONArray) {

            jsonArray = new JSONArray(jsonString);
            for (int i = 0; i < jsonArray.length(); i++) {

                String str = jsonArray.optString(i);

                if (str.startsWith("[")) {
                    AllValue(str, key, lists);
                } else {

                    JSONObject jo = jsonArray.optJSONObject(i);

                    Iterator<?> it;
                    try {
                        it = jo.keys();
                    } catch (Exception e) {
                        continue;
                    }

                    foreachJsonObject(key, jo, it, lists);
                }
            }
        }
        return lists;
    }

    private void foreachJsonObject(String key, JSONObject jsonObject, Iterator<?> it, List<String> list) {

        while (it.hasNext()) {

            String key$ = (String) it.next();

            if (key$.equals(key)) {

                list.add(jsonObject.optString(key));
            }
            AllValue(jsonObject.optString(key$), key, list);
        }
    }

    /**
     * 查询json字符，如果当前json对象包含目标键值对，就返回这个json对象的字符串
     */
    private JSONArray getOfKVs(String jsonString$, String key, String currentValue) throws JSONException {
        String jsonString = jsonString$.trim();
        if (!(jsonString.startsWith("{") || jsonString.startsWith("["))) {
            return null;
        }
        JSONObject jsonObject;
        JSONArray jsonArray;

        Object json = new JSONTokener(jsonString).nextValue();

        if (json instanceof JSONObject) {
            jsonObject = new JSONObject(jsonString);
            Iterator<?> it = jsonObject.keys();
            while (it.hasNext()) {
                String key$ = (String) it.next();
                if (key$.equals(key)) {
                    String value_ = jsonObject.optString(key);
                    if (value_.equals(currentValue)) {
                        arrays.put(jsonObject);
                    }
                } else {
                    getOfKVs(jsonObject.optString(key$), key, currentValue);
                }
            }

        } else if (json instanceof JSONArray) {

            jsonArray = new JSONArray(jsonString);
            for (int i = 0; i < jsonArray.length(); i++) {
                Object object = jsonArray.opt(i);

                if (object instanceof JSONArray) {//如果数组里面还有数组就再递归
                    getOfKVs(object.toString(), key, currentValue);
                }

                JSONObject jo = jsonArray.optJSONObject(i);
                Iterator<?> it;
                try {
                    it = jo.keys();
                } catch (Exception e) {
                    continue;
                }
                while (it.hasNext()) {

                    String key$ = (String) it.next();

                    if (key$.equals(key)) {

                        String value_ = jo.optString(key);
                        if (value_.equals(currentValue)) {
                            arrays.put(jsonArray.optJSONObject(i));

                        }
                    } else {
                        getOfKVs(jo.optString(key$), key, currentValue);
                    }
                }
            }
        }
        return arrays;
    }

    /**
     * 查询json字符，如果当前json对象包含目标键值对，就返回这个json对象的字符串
     *
     * @param jsonString$  变量的json字符串，
     * @param key          指定的key
     * @param currentValue key期望的value
     * @return key所在的jsonobject
     */
    public JSONArray getJSONObjectOfKVs(String jsonString$, String key, String currentValue) throws JSONException {
        arrays = new JSONArray();
        return getOfKVs(jsonString$, key, currentValue);
    }

    /**
     * 查询json字符，如果当前json对象包含目标键值对，就返回这个json对象的字符串
     *
     * @param jsonString$  变量的json字符串，
     * @param key          指定的key
     * @param currentValue key期望的value
     * @return key所在的jsonobject
     */
    public String getJSONObjectOfKV(String jsonString$, String key, String currentValue) throws JSONException {
        arrays = new JSONArray();

        JSONArray jsonArray = getOfKVs(jsonString$, key, currentValue);

        return Objects.requireNonNull(jsonArray).optString(0);
    }
}

